﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Xml.Linq;
using Puzzler.Plugin.Interface;
using Puzzler.Common;

namespace Plugin.Default.SwedenGrid
{
    public enum SwedenGridCellType
    {
        Character,
        Question
    }

    public enum SwedenGridCellDirection
    {
        Right,
        Bottom,
        Left,
        Top,
        LineTopDirectionRight,
        LineTopDirectionLeft,
        LineBottomDirectionRight,
        LineBottomDirectionLeft,
        LineLeftDirectionTop,
        LineLeftDirectionBottom,
        LineRightDirectionTop,
        LineRightDirectionBottom
    }

    public class SwedenGridCellContent : DependencyObject, INotifyPropertyChanged, ICloneable
    {
        public static readonly DependencyProperty CellDirectionProperty = DependencyProperty.Register(
            "CellDirection", typeof (SwedenGridCellDirection), typeof (SwedenGridCellContent),
            new PropertyMetadata(default(SwedenGridCellDirection)));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text", typeof (String), typeof (SwedenGridCellContent), new PropertyMetadata(default(String)));

        public event PropertyChangedEventHandler PropertyChanged;

        public SwedenGridCellDirection CellDirection
        {
            get { return (SwedenGridCellDirection) GetValue(CellDirectionProperty); }
            set { SetValue(CellDirectionProperty, value); }
        }

        public String Text
        {
            get { return (string) GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public SwedenGridCellContent()
        {
            CellDirection = SwedenGridCellDirection.Right;
            Text = "";
        }

        private SwedenGridCellContent(SwedenGridCellDirection cellDirection, string text)
        {
            CellDirection = cellDirection;
            Text = text;
        }

        public object Clone()
        {
            return new SwedenGridCellContent(CellDirection, Text);
        }

        protected bool Equals(SwedenGridCellContent other)
        {
            return CellDirection.Equals(other.CellDirection) && string.Equals(Text, other.Text);
        }

        public override string ToString()
        {
            return string.Format("CellDirection: {0}, Text: {1}", CellDirection, Text);
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            OnPropertyChanged(e.Property.Name);
        }

        protected void OnPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class SwedenGridCellInfo : GridCellInfo
    {
        public static readonly DependencyProperty CellTypeProperty = DependencyProperty.Register(
            "CellType", typeof (SwedenGridCellType), typeof (SwedenGridCellInfo),
            new PropertyMetadata(default(SwedenGridCellType)));

        public static readonly DependencyProperty CellContentProperty = DependencyProperty.Register(
            "CellContent", typeof (SwedenGridCellContent), typeof (SwedenGridCellInfo), new PropertyMetadata(null));

        public static readonly DependencyProperty AdditionalCellContentProperty = DependencyProperty.Register(
            "AdditionalCellContent", typeof (SwedenGridCellContent), typeof (SwedenGridCellInfo),
            new PropertyMetadata(null));

        public static readonly DependencyProperty ShowAlwaysProperty = DependencyProperty.Register(
            "ShowAlways", typeof (bool), typeof (SwedenGridCellInfo), new PropertyMetadata(false));

        public SwedenGridCellType CellType
        {
            get { return (SwedenGridCellType) GetValue(CellTypeProperty); }
            set { SetValue(CellTypeProperty, value); }
        }

        public SwedenGridCellContent CellContent
        {
            get { return (SwedenGridCellContent) GetValue(CellContentProperty); }
            set { SetValue(CellContentProperty, value); }
        }

        public SwedenGridCellContent AdditionalCellContent
        {
            get { return (SwedenGridCellContent) GetValue(AdditionalCellContentProperty); }
            set { SetValue(AdditionalCellContentProperty, value); }
        }

        /// <summary>
        /// Only for Characters
        /// </summary>
        public bool ShowAlways
        {
            get { return (bool) GetValue(ShowAlwaysProperty); }
            set { SetValue(ShowAlwaysProperty, value); }
        }

        public SwedenGridCellInfo()
        {
            CellType = SwedenGridCellType.Character;
            CellContent = new SwedenGridCellContent();
            AdditionalCellContent = null;
            ShowAlways = false;

            CellContent.PropertyChanged += (s, e) => OnPropertyChanged(CellContentProperty.Name);
            //AdditionalCellContent.PropertyChanged += (s, e) => OnPropertyChanged(AdditionalCellContentProperty.Name);
        }

        private SwedenGridCellInfo(SwedenGridCellType cellType, SwedenGridCellContent cellContent, SwedenGridCellContent additionalCellContent, bool showAlways)
        {
            CellType = cellType;
            CellContent = cellContent;
            AdditionalCellContent = additionalCellContent;
            ShowAlways = showAlways;

            CellContent.PropertyChanged += (s, e) => OnPropertyChanged(CellContentProperty.Name);
            AdditionalCellContent.PropertyChanged += (s, e) => OnPropertyChanged(AdditionalCellContentProperty.Name);
        }

        public override void CopyFrom(GridCellInfo cellInfo)
        {
            if (!(cellInfo is SwedenGridCellInfo))
                throw new ArgumentException("Wrong type for cellInfo!");

            SwedenGridCellInfo info = cellInfo as SwedenGridCellInfo;

            CellType = info.CellType;
            CellContent = (SwedenGridCellContent) info.CellContent.Clone();
            AdditionalCellContent = (SwedenGridCellContent) info.AdditionalCellContent.Clone();
        }

        public override object Clone()
        {
            return new SwedenGridCellInfo(CellType, CellContent, AdditionalCellContent, ShowAlways);
        }

        protected bool Equals(SwedenGridCellInfo other)
        {
            return CellType.Equals(other.CellType) && Equals(CellContent, other.CellContent) && Equals(AdditionalCellContent, other.AdditionalCellContent) && ShowAlways.Equals(other.ShowAlways);
        }

        public override string ToString()
        {
            return string.Format("CellType: {0}, CellContent: {1}, AdditionalCellContent: {2}, ShowAlways: {3}", CellType, CellContent, AdditionalCellContent, ShowAlways);
        }
    }
}
